﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using TTUnityPlugin;
using TTGameEngine;

namespace TTGame {

class AudioConfigItem {
    public string namePrefix;
    public string pathPrefix;
    public ResSuffixStr suffixType;

    public AudioConfigItem(string[] values) {
        namePrefix = values[0];
        pathPrefix = values[1];
        suffixType = (ResSuffixStr)int.Parse(values[2]);
    }

    public string Key {
        get { return namePrefix; }
    }
}


/*
 * 负责加载【AudioClip】。
 *
 * You Should Know
 * Audio使用名字加载即可。Audio文件的名字拥有前缀，由此知道所在的目录
 *
 * 前缀： bgm_ , voice_,
 *
 * 特别注意：
 * LoadClipList()方法 不同后缀名的音效不能放在一个列表加载。
 */

public class AudioClipLoader : ObjectLoader {

    //根据ResSuffixStr枚举。 ResSuffixStr.wav = 2  ResSuffixStr.mp3 = 3
    //会查找Resources/Sounds里面的声音资源
    const string AudioPathDefault = "default";
    string[][] AudioPathInfos = {
        new string[3]{"bgm",    "default/PVE/Sounds/BGM/",      "3"},
        new string[3]{"CG",  "default/PVE/Sounds/Effect/",    "3"},
        new string[3]{"PVE",  "default/PVE/Sounds/Effect/",    "3"},
        new string[3]{"player", "default/PVE/Sounds/Effect/",   "3"},
        new string[3]{"gun",    "default/PVE/Sounds/Guns/",     "3"},
        new string[3]{"bullet", "default/PVE/Sounds/Guns/",     "3"},
        new string[3]{AudioPathDefault, "Sounds/",  "3"}
    };
    Dictionary<string, AudioConfigItem> audioPathTable = new Dictionary<string, AudioConfigItem>();

    const ResSuffixStr DefaultAuidoSuffix = ResSuffixStr.mp3;

    #region Load Public Method

    void Awake() {
        for(int i = 0; i < AudioPathInfos.Length; i++) {
            AudioConfigItem item = new AudioConfigItem(AudioPathInfos[i]);
            audioPathTable.Add(item.Key, item);
        }
    }

    public void LoadClip(string name, Func_LoadResOK func) {
        if(string.IsNullOrEmpty(name)) {
            if(func != null) {
                func(name, null);
            }

        } else {
            string audioPath = "";
            ResSuffixStr suffix = DefaultAuidoSuffix;
            getAudioPathAndSuffix(name, out audioPath, out suffix);
            if(func != null) {
                PreloadPrefab(audioPath, (path, obj) => {
                    func(name, obj);
                }, suffix);

            } else {
                PreloadPrefab(audioPath, null, suffix);
            }
        }
    }

    //注1：不同后缀名的音效不能放在一个列表加载。
    //注2：ClipList不提供回调。回调中name的获取太麻烦。
    public void LoadClipList(string[] names, Func_LoadResOK func = null) {
        if(names.Length == 0 && func == null) {
            return;
        }
        ResSuffixStr suffix = getAudioSuffixWithName(names[0]);
        List<string> nameList = new List<string>();
        for(int i = 0; i < names.Length; i++) {
            string name = names[i];
            nameList.Add(getAudioPathWithName(name));
        }
        PreloadPrefabList(nameList, null, suffix);
    }

    public AudioClip GetClip(string name) {
        return GetPrefabObj(getAudioPathWithName(name)) as AudioClip;
    }

    public bool IsClipLoaded(string name) {
        if(string.IsNullOrEmpty(name)) {
            return false;
        }
        return IsPrefabExist(getAudioPathWithName(name));
    }
    #endregion
    //=======================================================

    #region Load Private Method


    public string getAudioPathWithName(string name) {
        if(string.IsNullOrEmpty(name)) {
            return "";
        }
        return getAudioConfigItem(name).pathPrefix + name;
    }

    ResSuffixStr getAudioSuffixWithName(string name) {
        if(string.IsNullOrEmpty(name)) {
            return DefaultAuidoSuffix;
        }
        return getAudioConfigItem(name).suffixType;
    }

    void getAudioPathAndSuffix(string name, out string audioPath, out ResSuffixStr suffix) {
        AudioConfigItem item = null;
        if(!string.IsNullOrEmpty(name)) {
            item = getAudioConfigItem(name);
        }
        if(item == null) {
            audioPath = "";
            suffix = DefaultAuidoSuffix;
            return;
        }
        audioPath = item.pathPrefix + name;
        suffix = item.suffixType;
    }

    char[] pathSplitChars = new char[] { '_' }; // >_<
    AudioConfigItem getAudioConfigItem(string name) {
        //string namePrefix = name.Split(pathSplitChars)[0];
        int idx = name.IndexOf("_");
        string namePrefix;
        if(idx > 0) {
            namePrefix = name.Substring(0, idx);
        } else {
            namePrefix = AudioPathDefault;
        }
        AudioConfigItem item = null;
        audioPathTable.TryGetValue(namePrefix, out item);
        if(item == null) {
            DebugUtil.LogErrorFormat("[AudioClipLoader] cannot found audio info. name[{0}]", name);
        }
        return item;
    }

    public void ClearAudioMemory(string audioName) {
        ResCache cache = null;
        string audioPath = getAudioPathWithName(audioName);
        if(cachedPrefabs.TryGetValue(audioPath, out cache)) {
            Resources.UnloadAsset(cache.resObj);
            cache.Init();
            cachedPrefabs.Remove(audioPath);
        }
    }

    #endregion
}

}